from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

from qturboframe.lib.webdriver.remote.webdriver import WebDriver
from qturboframe.lib.webdriver.remote.webelement import WebElement
from qturboframe.lib.utils.TimeMeta import TimeMeta
from qturboframe.lib.utils.CustomError.custom_error import CustomError
from qturboframe.lib.utils.CustomError.custom_exception import CustomException
from qturboframe.lib.webdriver.exceptions import SeleniumError


class BaseElement(TimeMeta):
    '''
    web组件基础控件类

    :Attributes:
     - driver: 控件所在的当前webdriver对象
     - element: 控件元素webelement对象
     - timeout: 步骤操作的超时时间

    :Example:
     - 例1: BaseElement(webelement)
     - 例2: BaseElement('id')
     - 例3: BaseElement({By.NAME:'name'})
     - 例4: BaseElement({By.CLASS_NAME:'class_name','text':'文本信息'})
     - 例5: BaseElement({By.CLASS_NAME:'class_name','text':'文本信息'}, father=driver)
     - 例6: BaseElement({By.CLASS_NAME:'class_name','text':'文本信息'}, father=webelement)
    '''

    def __init__(self, element_para, father=None, timeout=5):
        # element_para入参为字符串类型时，默认为查询方式为id
        if isinstance(element_para, str):
            element_para = {By.ID:element_para}
            self.locator_by = By.ID
            self.locator = element_para
        if isinstance(element_para, WebElement):
            self._element = element_para
            self._driver = element_para._parent
            self.timeout = timeout
        elif not isinstance(element_para, dict):
            message = 'element_para参数类型不正确！'
            raise SeleniumError(CustomError.Error_EQ03008001_Parameter_InCorrect, message)
        else:
            if father is None:
                message = '未定位元素，father参数不能为None！'
                raise SeleniumError(CustomError.Error_EQ03008001_Parameter_InCorrect, message)
            if isinstance(father, WebDriver):
                self._driver = father
                self.timeout = timeout
            elif isinstance(father, WebElement):
                self._driver = father._parent
                self.timeout = timeout
            else:
                message = 'father参数类型不正确！'
                raise SeleniumError(CustomError.Error_EQ03008001_Parameter_InCorrect, message)
            key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                        By.PARTIAL_LINK_TEXT,By.CSS_SELECTOR, By.XPATH]
            element_by = ''
            element_value = ''
            assist = ''
            for key, value in element_para.items():
                if key in key_list:
                    element_by = key
                    element_value = value
                else:
                    assist += '{}:{},'.format(key, value)
            assist = assist.strip(',')
            self._element = father.find_element_by_attribute(
                element_by, element_value, assist, self.timeout)
            self.locator_by = element_by
            self.locator = element_value

    def get_text(self):
        '''
        获取元素的文本

        :Returns:
            返回元素的文本

        :Example:
         - 例: text = base_element.get_text()
        '''
        return self._element.text

    def click(self):
        '''
        点击元素

        :Example:
         - 例: base_element.click()
        '''
        self._element.secure_click()

    @property
    def element(self):
        '''
        获取元素webelement对象

        :Returns:
            返回元素webelement对象

        :Example:
         - 例: element = base_element.element
        '''
        return self._element

    def hove_element(self):
        '''
        悬浮到元素上

        :Example:
         - 例: base_element.hove_element()
        '''
        actions = ActionChains(self._driver)
        actions.move_to_element(self.element).perform()